﻿using System.Diagnostics;
using System.Text;
using AutoTest.Framework.Exceptions;
using AutoTest.Framework.Ioc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

namespace AutoTest.Framework.Api
{

    /// <summary>
    /// Api公共返回
    /// </summary>
    public class ApiResult
    {
        public ApiResult()
        {
            var environment = ServiceLocator.ServiceProvider?.GetService<IHostEnvironment>();
            Env = environment?.EnvironmentName ?? "Unknown";
        }

        public ApiResult(Exception ex) : this()
        {
            Code = 500;
            ExceptionMsg = ex.Message;
            Msg = ex.Message;
        }
        /// <summary>
        /// 接口是否调用成功
        /// </summary>
        public bool Succ { get; set; } = true;

        /// <summary>
        /// 错误码200：成功，其他自己定义
        /// </summary>
        public int Code { get; set; } = 200;

        /// <summary>
        /// 错误消息
        /// </summary>
        public string Msg { get; set; } = string.Empty;

        public string ExceptionMsg { get; set; } = string.Empty;
        /// <summary>
        /// 异常信息
        /// </summary>
        //public Exception? Ex { get; set; }

        /// <summary>
        /// 异常详细信息
        /// </summary>
        //public string ExceptionMsg
        //{
        //    get
        //    {
        //        var msgBulder = new StringBuilder();
        //        if (Ex != null)
        //        {
        //            msgBulder.AppendLine(Ex.Message + Environment.NewLine + Ex.StackTrace);

        //        }

        //        return msgBulder.ToString();
        //    }
        //}


        /// <summary>
        /// 请求耗时(毫秒）
        /// </summary>
        public long ExcuteMiniSeconds { get; set; }

        public string Env { get; set; } = "";

        public static ApiResult FromResult(Action action)
        {
            var result = new ApiResult();
            var watch = new Stopwatch();
            watch.Start();
            try
            {
                action();
            }
            catch (BusinessException byex)
            {
                result.Succ = true;
                result.Msg = byex.Message;
                result.Code = 505;
            }
            catch (Exception ex)
            {
                result.Succ = false;
                //result.Ex = ex;
                result.ExceptionMsg = ex.Message;
                result.Msg = "网络异常，请稍后再试";
                Log.Error(ex.Message, ex);
                result.Code = 500;
            }
            watch.Stop();
            result.ExcuteMiniSeconds = watch.ElapsedMilliseconds;
            return result;
        }

        public static async Task<ApiResult> FromResult(Func<Task> action)
        {
            var result = new ApiResult();
            var watch = new Stopwatch();
            watch.Start();
            try
            {
                await action();
            }
            catch (BusinessException byex)
            {
                result.Succ = true;
                result.Msg = byex.Message;
                result.Code = 505;
                Log.Error(byex.Message, byex);
            }
            catch (Exception ex)
            {
                result.Succ = false;
                result.ExceptionMsg = ex.Message;
                result.Msg = "网络异常，请稍后再试";
                Log.Error(ex.Message, ex);
                result.Code = 500;
            }
            watch.Stop();
            result.ExcuteMiniSeconds = watch.ElapsedMilliseconds;
            return result;
        }


        public static ApiResult Failed()
        {
            return new ApiResult() { Code = 500 };
        }
        public static ApiResult Failed(int code, string errorMsg = "")
        {
            return new ApiResult() { Code = code, Msg = errorMsg };
        }

        public static ApiResult Failed(Exception ex)
        {
            return new ApiResult(ex);
        }
        public static ApiResult Successed()
        {
            return new ApiResult() { Code = 200, Msg = "成功", };
        }
    }
    /// <summary>
    /// Api公共返回
    /// </summary>
    public class ApiResult<T> : ApiResult
    {
        public ApiResult() : base()
        {
            Data = default!;
        }
        /// <summary>
        /// 返回的内容数据
        /// </summary>
        public T Data { get; set; }

        public static ApiResult<T> Successed(T data)
        {
            return new ApiResult<T>() { Code = 200, Msg = "成功", Data = data };
        }

        public static async Task<ApiResult<T>> Successed(Func<Task<T>> action)
        {
            var result = new ApiResult<T>();
            var watch = new Stopwatch();
            watch.Start();
            try
            {
                //result.Data = await action();
                var resultTask = action();
                await resultTask;
                if (resultTask.Exception != null) throw resultTask.Exception;
                result.Data = resultTask.Result;
            }
            catch (BusinessException byex)
            {
                result.Succ = true;
                result.Msg = byex.Message;
                result.Code = 505;
                Log.Error(byex.Message, byex);
            }
            catch (Exception ex)
            {
                result.Succ = false;
                result.ExceptionMsg = ex.Message;
                result.Msg = "网络异常，请稍后再试";
                Log.Error(ex.Message, ex);
                result.Code = 500;
            }
            watch.Stop();
            result.ExcuteMiniSeconds = watch.ElapsedMilliseconds;
            return result;
        }

        public static ApiResult<T> Successed(Func<T> action)
        {
            var result = new ApiResult<T>();
            var watch = new Stopwatch();
            watch.Start();
            try
            {
                result.Data = action();
            }
            catch (BusinessException byex)
            {
                result.Succ = true;
                result.Msg = byex.Message;
                result.Code = 505;
                Log.Error(byex.Message, byex);
            }
            catch (Exception ex)
            {
                result.Succ = false;
                result.ExceptionMsg = ex.Message;
                result.Msg = "网络异常，请稍后再试";
                Log.Error(ex.Message, ex);
                result.Code = 500;
            }
            watch.Stop();
            result.ExcuteMiniSeconds = watch.ElapsedMilliseconds;
            return result;
        }
    }
}
